if (!folderplus)
	var folderplus = {};
	
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource://gre/modules/FileUtils.jsm");

folderplus.options = {
	
	// pseudo constante
  BLACKLISTFILENAME : "folderplus.dat",
  
  /**
	 * Read last blackList from FS and store it in memory.
	 */
	readBlackList : function () {
		var file = FileUtils.getFile("ProfD", [this.BLACKLISTFILENAME]);
		NetUtil.asyncFetch(file, function(inputStream, status) {
			if (!Components.isSuccessCode(status)) {
				// Handle error!
				Components.utils.reportError("error reading black listed folders");
				return;
			}
			// The file data is contained within inputStream.
			// You can read it into a string with
			// In case of empty file, then an exception, so _blackListURIs is not modified.
			var data = NetUtil.readInputStreamToString(inputStream, inputStream.available());
			folderplus.conv._blackListURIs = data.split("|");
			var count = folderplus.conv._blackListURIs.length;
			if (folderplus.conv._blackListURIs[0] == "") {
				count = 0;
			}
			folderplus.log("read black list : " + count);
		});
	},
	
	writeBlackList : function () {
		var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                   .getService(Components.interfaces.nsIWindowMediator);
		var browserWindow = wm.getMostRecentWindow("mail:3pane");

		var data = browserWindow.folderplus.conv._blackListURIs.join("|");
		
		var file = FileUtils.getFile("ProfD", [this.BLACKLISTFILENAME]);
		
		// You can also optionally pass a flags parameter here. It defaults to
		// FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE;
		var ostream = FileUtils.openSafeFileOutputStream(file)
		
		var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].
					 createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
		converter.charset = "UTF-8";
		var istream = converter.convertToInputStream(data);
		
		// The last argument (the callback) is optional.
		NetUtil.asyncCopy(istream, ostream, function(status) {
			if (!Components.isSuccessCode(status)) {
				Components.utils.reportError("error writing black listed folders");
				return;
			}
		   
			// Data has been written to the file.
			//@ test vérifier la génération du fichier.
			//@ test vérifier le format du fichier.
			//@ test vérifier qu'au 2 dossier blaclistés, le fichier contient la concaténation par des |.
		});
	},
	
	chooseFoldersToBlackList : function () {
		// if we have some search folders already, then root the folder picker dialog off the account
		// for those folders. Otherwise fall back to the preselectedfolderURI which is the parent folder
		// for this new virtual folder.
        var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                   .getService(Components.interfaces.nsIWindowMediator);
		var browserWindow = wm.getMostRecentWindow("mail:3pane");
		var data = browserWindow.folderplus.conv._blackListURIs.join("|");
		//@ test vérifier à l'ouverture de la fenêtre qu'on récupére bien la blacklist courante
		//@ test tester avec 2 dossiers blaclistés et vérifier qu'on récupére au moins 2 dossiers
		//@ todo essayer de changer le libelle 'à chercher'
		var dialog = window.openDialog("chrome://messenger/content/virtualFolderListDialog.xul", "",
							 "chrome,titlebar,modal,centerscreen,resizable",
							 {searchFolderURIs:data,
							  okCallback:folderplus.options.onFolderListDialogCallback});
	},
	
	/**
	 * @param searchFolderURIs String folderURI join by '|', "" if no folder selected
	 */
	onFolderListDialogCallback : function (searchFolderURIs) {
		var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                   .getService(Components.interfaces.nsIWindowMediator);
		var browserWindow = wm.getMostRecentWindow("mail:3pane");

		//@ test vérifier que la blackList en mémoire est tout de suite prise en compte dans l'algo
		browserWindow.folderplus.conv._blackListURIs = searchFolderURIs.split("|");
		
		folderplus.options.writeBlackList();
	},
    
    init : function () {
		var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                   .getService(Components.interfaces.nsIWindowMediator);
		var browserWindow = wm.getMostRecentWindow("mail:3pane");
		document.getElementById("folderplus.stat.sessionsearchcount").value = 
            browserWindow.folderplus.stats.sessionSearchCount;
		document.getElementById("folderplus.stat.sessionTotalTime").value = 
            browserWindow.folderplus.stats.sessionSearchCount == 0 ? "0"
			:  (browserWindow.folderplus.stats.sessionSearchTotalTime / browserWindow.folderplus.stats.sessionSearchCount).toFixed();
		document.getElementById("folderplus.stat.sessionglodamissed").value = 
            browserWindow.folderplus.stats.sessionGlodaMessageMissed;
		document.getElementById("folderplus.stat.last").value = 
            browserWindow.folderplus.stats.toString(browserWindow.folderplus.stats.lastStat);
	}
};

folderplus.folderListener = {
	
	//@ test créer test, testbis dans test et test2, les mettre dans la blacklist, renommer test en toto, déplacer et le détruire.
	folderRenamed : function(aOrigFolder, aNewFolder) {
		folderplus.log("rename folder " + aOrigFolder.URI);
		//@ test vérifier le renommage du dossier et de tous les sous-dossiers.
		var needWrite = folderplus.conv._updateBlackListWithURI(aOrigFolder.URI, aNewFolder.URI);
		if (needWrite) {
			folderplus.options.writeBlackList();
		}
	},
   
	/*
	 * @param aMove boolean
	 */
	folderMoveCopyCompleted : function(aMove, aOrigFolder, aNewFolder) {
		/* When moving an arbo, called once */
		folderplus.log("move folder " + aOrigFolder.URI);
		if (aMove) {
			var targetURI = aNewFolder.URI +
				aOrigFolder.URI.substring(aOrigFolder.URI.lastIndexOf("/"));
			//@ test vérifier le déplacement du dossier et de tous les sous-dossiers.
			//@ test cas test, test2 qui sont blacklistés, déplacer test, test2 reste blacklisté
			var needWrite = folderplus.conv._updateBlackListWithURI(aOrigFolder.URI, targetURI);
			if (needWrite) {
				folderplus.options.writeBlackList();
			}
		}
	},
	
	folderDeleted : function(aFolder) {
		/* called only when trash is empty, when moving an arbo, called once for each folder. */    
		folderplus.log("delete folder " + aFolder.URI);
		for (var i = 0; i < folderplus.conv._blackListURIs.length; i++) {
			if (folderplus.conv._blackListURIs[i] == aFolder.URI) {
				folderplus.conv._blackListURIs.splice(i, 1);
				folderplus.options.writeBlackList();
				return;
			}
		}
	}
}

folderplus.prefObserver = {
  register: function() {
    // First we'll need the preference services to look for preferences.
    var prefService = Components.classes["@mozilla.org/preferences-service;1"]
                                .getService(Components.interfaces.nsIPrefService);

    // For this.branch we ask for the preferences for extensions.folderplus. and children
    this.branch = prefService.getBranch("extensions.folderplus.");

    // Now we queue the interface called nsIPrefBranch2. This interface is described as:  
    // "nsIPrefBranch2 allows clients to observe changes to pref values."
    // This is only necessary prior to Gecko 13
    if (!("addObserver" in this.branch))
        this.branch.QueryInterface(Components.interfaces.nsIPrefBranch2);

    // Finally add the observer.
    this.branch.addObserver("", this, false);
  },

  unregister: function() {
    this.branch.removeObserver("", this);
  },

  observe: function(aSubject, aTopic, aData) {
    // aSubject is the nsIPrefBranch we're observing (after appropriate QI)
    // aData is the name of the pref that's been changed (relative to aSubject)
    var prefService = Components.classes["@mozilla.org/preferences-service;1"]
                            .getService(Components.interfaces.nsIPrefService);
    switch (aData) {
      case "searchlevel":
		var searchlevel = prefService.getIntPref("extensions.folderplus.searchlevel");
		folderplus.conv.searchLevel = searchlevel;
        break;
      case "searchPrefixe":
		var searchPrefixe = prefService.getCharPref("extensions.folderplus.searchPrefixe");
		folderplus.conv.searchPrefixe = searchPrefixe;
        break;
    }
  }
}
folderplus.prefObserver.register();